package com.huawang.mdesign.model.service.model.base;

import com.huawang.business.constants.ModelConstantURI;
import com.huawang.business.service.model.base.ModelManagerConfig;
import com.huawang.core.definition.mof.UMLDefinitionConstants;
import com.huawang.core.definition.mof.instances.MetaClassInstance;
import com.huawang.core.semantics.service.query.IHierarchyService;
import com.huawang.core.semantics.service.query.IJudgeService;
import com.huawang.mdesign.model.service.constant.SpringBeanNameConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Component(SpringBeanNameConstants.ELEMENT_DEFINE_SERVICE)
@Primary
public class UAFElementDefineService extends com.huawang.business.service.model.base.ElementDefineService {
    @Autowired
    private IJudgeService iJudgeService;

    @Autowired
    private IHierarchyService iHierarchyService;

    @Autowired
    private ModelManagerConfig modelManagerConfig;

    private static final String SYSML_PREFIX = "SysML::";
    private static final String SYSML_DI_PREFIX = "SysMLDI::";
    private static final String UAF_PREFIX = "UAF::";
    private static final String CUSTOMIZATION_PREFIX = "Customization::";
    private static final String TABLE_AND_MATRIX_PREFIX = "TableAndMatrix::";
    private static final String UI_PROTOTYPING_PREFIX = "UIPrototyping::";
    private static final String SIMULATION_PREFIX = "Simulation::";
    private static final String UML_DESIGN_PROFILE_PREFIX = "UML::Design Profile::";
    private static final String RELIABILITY_PROFILE_PREFIX = "ReliabilityProfile::";
    private static final Set<String> PREFIXES = Stream.of(SYSML_PREFIX, SYSML_DI_PREFIX, UAF_PREFIX, CUSTOMIZATION_PREFIX, TABLE_AND_MATRIX_PREFIX,
                    UI_PROTOTYPING_PREFIX, SIMULATION_PREFIX, UML_DESIGN_PROFILE_PREFIX, RELIABILITY_PROFILE_PREFIX, UMLDefinitionConstants.TableAndMatrix_DigramGrantt)
            .collect(Collectors.toSet());

    /**
     * 根据多个实例获取基础构造型
     *
     * @param projectId
     * @param instances
     * @return
     */
    @Override
    @Nullable
    public String queryBaseStereotype(String projectId, @Nullable List<MetaClassInstance> instances) {
        final List<MetaClassInstance> noHideInstance = Objects.nonNull(instances) ?
                instances.stream()
                        .filter(it -> !ModelConstantURI.NotHideMeteTypeStereoTypeList.contains(it.getId()))
                        .collect(Collectors.toList()) :
                Collections.emptyList();
        for (MetaClassInstance metaClassInstance : noHideInstance) {
            final String baseStereotype = this.queryBaseStereotype(projectId, metaClassInstance);
            if (Objects.nonNull(baseStereotype)) {
                return baseStereotype;
            }
        }
        return null;
    }

    /**
     * 根据实例获取基础构造型
     *
     * @param projectId
     * @param instance
     * @return
     */
    @Override
    @Nullable
    public String queryBaseStereotype(@NotNull String projectId, @NotNull MetaClassInstance instance) {
        final List<MetaClassInstance> generalsCascade = this.iHierarchyService.getGeneralsCascade(projectId, instance, true);
        for (MetaClassInstance general : generalsCascade) {
            final String generalId = general.getId();
            if (PREFIXES.stream().anyMatch(generalId::startsWith)) {
                if (this.iJudgeService.isGivenMetaModelType(projectId, general,
                        UMLDefinitionConstants.Design_Profile_InvisibleStereotype)) {
                    continue;
                }
                if (modelManagerConfig.getStTypeConfig().contains(generalId)) {
                    return generalId;
                }
                // 甘特图
                if(UMLDefinitionConstants.TableAndMatrix_DigramGrantt.equals(generalId) &&
                        modelManagerConfig.getStTypeConfig().contains(generalsCascade.get(0).getUUID())) {
                    return generalsCascade.get(0).getUUID();
                }
            }
        }

        return null;
    }
}
